package com.jiaxianm.secure.aop;

import com.jiaxianm.secure.annotation.ResponseEncrypt;
import com.jiaxianm.secure.entity.R;
import com.jiaxianm.secure.utils.AESUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @ClassName : ResponseEncryptAOP
 * @Description : 传输加密模块AOP，对接口的出参进行加密，注意顺序不能乱，
 * 此AOP必须第一个执行，因为最先执行的最后结束，这样才能在各个AOP都执行完毕之后完成最后的加密
 */

@Order(value = 0)
@Aspect
@Component
public class ResponseEncryptAop {

    @Pointcut("@annotation(com.jiaxianm.secure.annotation.ResponseEncrypt)")
    public void point(){}

    /**
     * 环绕增强，加密出参
     * */
    @Around(value = "point() && @annotation(responseEncrypt)")
    public Object aroundEncrypt(ProceedingJoinPoint joinPoint, ResponseEncrypt responseEncrypt) throws Throwable {
        //返回的结合
        Object returnValue = null;
        //从上下文中提取
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

        //业务执行返回结果
        returnValue = joinPoint.proceed();
        System.out.println("returnValue.toString() = " + returnValue.toString());

        //获取到前端传递过来的AES密钥，然后对响应数据进行AES加密操作
        String aesKey = request.getParameter("aesKey");
        System.out.println("aesKey = " + aesKey);
        String encryptToBase64Data = AESUtil.encryptToBase64(returnValue.toString(), aesKey);
        returnValue = R.ok(encryptToBase64Data);
        return returnValue;
    }
}
